package demo1;

import org.junit.Test;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Objects;
import java.util.Scanner;


/*
对于 Buffer 来说，另一个常见的操作中就是，我们要将来自 Channel 的数据填充到 Buffer 中，
在系统层面上，这个操作我们称为读操作，因为数据是从外部（文件或网络等）读到内存中。
通常在说 NIO 的读操作的时候，我们说的是从 Channel 中读数据到 Buffer 中，对应的是对 Buffer 的写入操作，初学者需要理清楚这个。
        int num = channel.read(buf);
        上述方法会返回从 Channel 中读入到 Buffer 的数据大小。

调用 Buffer 的 flip() 方法，可以从写入模式切换到读取模式。其实这个方法也就是设置了一下 position 和 limit 值罢了。

除了将数据从 Buffer 取出来使用，更常见的操作是将我们写入的数据传输到 Channel 中，
如通过 FileChannel 将数据写入到文件中，通过 SocketChannel 将数据写入网络发送到远程机器等。
对应的，这种操作，我们称之为写操作。
int num = channel.write(buf);


*/



/**
 * Created by ascend on 2017/6/13 10:36.
 */
public class Client {

  @Test
  public void test() {
    Socket socket = new Socket();
    try {
      socket.connect(new InetSocketAddress(SelectorServer.REMOTE_IP, SelectorServer.PORT));
      DataOutputStream out = new DataOutputStream(socket.getOutputStream());
      out.write("exit".getBytes());
      out.flush();
      out.close();
      socket.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    new Thread(new ClientThread()).start();
  }

  public void checkStatus(String input) {
    if ("exit".equals(input.trim())) {
      System.out.println("系统即将退出，bye~~");
      System.exit(0);
    }
  }


}

class ClientThread implements Runnable {
  private SocketChannel sc;
  private boolean isConnected = false;
  Client client = new Client();

  public ClientThread() {
    try {
      sc = SocketChannel.open();
      sc.configureBlocking(false);
      sc.connect(new InetSocketAddress(SelectorServer.REMOTE_IP, SelectorServer.PORT));
      while (!sc.finishConnect()) {
        System.out.println("同" + SelectorServer.REMOTE_IP + "的连接正在建立，请稍等！");
        Thread.sleep(10);
      }
      System.out.println("连接已建立，待写入内容至指定ip+端口！时间为" + System.currentTimeMillis());

    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void run() {
    try {
      while (true) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要发送的内容：");
        String writeStr = scanner.nextLine();
        client.checkStatus(writeStr);
        ByteBuffer bb = ByteBuffer.allocate(writeStr.length());
        bb.put(writeStr.getBytes());
        // Buffer 切换为读模式
        bb.flip(); // 写缓冲区的数据之前一定要先反转(flip)
        while (bb.hasRemaining()) {
          // 将 Buffer 中的内容写入文件
          sc.write(bb);
        }
        bb.clear();
      }
    } catch (IOException e) {
      e.printStackTrace();
      if (Objects.nonNull(sc)) {
        try {
          sc.close();
        } catch (IOException e1) {
          e1.printStackTrace();
        }
      }
    } finally {
      if (Objects.nonNull(sc)) {
        try {
          sc.close();
        } catch (IOException e1) {
          e1.printStackTrace();
        }
      }
    }
  }
}